﻿namespace Pub.Class
{
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;

    public abstract class MemoryHelper
    {
        protected MemoryHelper()
        {
        }

        [DllImport("kernel32.dll")]
        private static extern void CloseHandle(IntPtr hObject);
        public static IntPtr FindWindow(string title)
        {
            foreach (Process process in Process.GetProcesses())
            {
                if (process.MainWindowTitle.IndexOf(title) != -1)
                {
                    return process.MainWindowHandle;
                }
            }
            return IntPtr.Zero;
        }

        public static int GetPID(string windowTitle)
        {
            foreach (Process process in Process.GetProcesses())
            {
                if (process.MainWindowTitle.IndexOf(windowTitle) != -1)
                {
                    return process.Id;
                }
            }
            return 0;
        }

        public static int GetPIDByProcessName(string processName)
        {
            Process[] processesByName = Process.GetProcessesByName(processName);
            int index = 0;
            while (index < processesByName.Length)
            {
                Process process = processesByName[index];
                return process.Id;
            }
            return 0;
        }

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
        public static int ReadMemoryValue(int baseAddress, string processName)
        {
            try
            {
                byte[] arr = new byte[4];
                IntPtr lpBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0);
                IntPtr hProcess = OpenProcess(0x1f0fff, false, GetPIDByProcessName(processName));
                ReadProcessMemory(hProcess, (IntPtr) baseAddress, lpBuffer, 4, IntPtr.Zero);
                CloseHandle(hProcess);
                return Marshal.ReadInt32(lpBuffer);
            }
            catch
            {
                return 0;
            }
        }

        [DllImport("kernel32.dll")]
        public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, IntPtr lpNumberOfBytesRead);
        public static void WriteMemoryValue(int baseAddress, string processName, int value)
        {
            IntPtr hProcess = OpenProcess(0x1f0fff, false, GetPIDByProcessName(processName));
            WriteProcessMemory(hProcess, (IntPtr) baseAddress, new int[] { value }, 4, IntPtr.Zero);
            CloseHandle(hProcess);
        }

        [DllImport("kernel32.dll")]
        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, int[] lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);
    }
}

